package com.cscj.android.repository.repo.search

import androidx.room.withTransaction
import com.cscj.android.repository.db.CacheDatabase
import com.cscj.android.repository.db.dao.HotSearchDao
import com.cscj.android.repository.db.dao.SearchEngineDao
import com.cscj.android.repository.db.dao.SearchHistoryDao
import com.cscj.android.repository.db.entity.HotSearchEntity
import com.cscj.android.repository.db.entity.SearchEngineEntity
import com.cscj.android.repository.db.entity.SearchHistoryEntity
import com.cscj.android.repository.network.Result
import com.cscj.android.repository.network.ResultFlowTransformer
import com.cscj.android.repository.network.api.service.RankService
import kotlinx.coroutines.flow.Flow
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import java.util.Date

class SearchRepositoryImpl : SearchRepository, KoinComponent {

    private val searchHistoryDao by inject<SearchHistoryDao>()

    private val searchEngineDao by inject<SearchEngineDao>()

    private val hotSearchDao by inject<HotSearchDao>()

    private val database by inject<CacheDatabase>()

    private val transformer by inject<ResultFlowTransformer>()

    private val rankService by inject<RankService>()

    override fun searchList(): Flow<List<SearchHistoryEntity>> {
        return searchHistoryDao.getSearchHistory()
    }

    override suspend fun saveSearchHistory(keyword: String) {
        searchHistoryDao.upsertSearchHistory(
            SearchHistoryEntity(
                key = keyword, updateTime = Date()
            )
        )
    }

    override suspend fun deleteAllSearchHistory() {
        searchHistoryDao.deleteAllSearchHistory()
    }


    override suspend fun deleteSearchHistory(searchHistoryEntity: SearchHistoryEntity) {
        searchHistoryDao.deleteSearchHistory(searchHistoryEntity)
    }


    override fun searchEngines(): Flow<List<SearchEngineEntity>> {
        return searchEngineDao.engineList()
    }

    override suspend fun switchEngine(id: Int) {
        database.withTransaction {
            searchEngineDao.updatePreferred(false)
            searchEngineDao.updatePreferredById(id, true)
        }
    }

    override fun currentSearchEngine(): Flow<SearchEngineEntity?> {
        return searchEngineDao.currentEngine()
    }

    override fun hotSearchList(sourceType: Int): Flow<List<HotSearchEntity>> {
        return hotSearchDao.getHotSearchList(sourceType)
    }

    override fun searchRecommendList(): Flow<List<HotSearchEntity>> {
        return hotSearchDao.getSearchRecommend(5)
    }

    override fun searchRecommendNewList(): Flow<List<HotSearchEntity>> {
        return hotSearchDao.getSearchRecommend(10)
    }

    override suspend fun loadHotSearch() {
        loadHotSearch(HotSearchEntity.SourceTypeBaidu)
        loadHotSearch(HotSearchEntity.SourceTypeTouTiao)
        loadHotSearch(HotSearchEntity.SourceTypeWeibo)
        loadHotSearch(HotSearchEntity.SourceTypeZhihu)
        loadHotSearch(HotSearchEntity.SourceTypeZongYi)
    }

    private suspend fun loadHotSearch(type: Int, limit: Int = 10): Result<Unit> {
        return transformer.asResult(networkCall = {
            rankService.loadRank(type, limit)
        }, successCall = {
            database.withTransaction {
                val rankList = it.data.map { rank ->
                    HotSearchEntity(
                        id = rank.id,
                        sourceType = type,
                        content = rank.title,
                        order = rank.sort,
                        url = rank.url
                    )
                }

                hotSearchDao.deleteByType(type)
                hotSearchDao.batchInsert(rankList)
            }

        }, transformer = {})
    }

}